home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Arsenal Files 4
/
The Arsenal Files 4 (Arsenal Computer).ISO
/
casm
/
au116-as.exe
/
UTIL
/
GETREC.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1994-11-15
|
31KB
|
1,434 lines
#include "..\au.hpp"
#include <time.h>
#define SZ_NAME 80
/***********************************************************************/
#if SUPPORT_DWC || SUPPORT_LZH || SUPPORT_HA
static void my_localtime(time_t t, ARC_RECORD *r)
{
struct tm *tm;
tm = localtime(&t); // Expensive function, costs 4K
r->date.year = tm->tm_year;
r->date.month = tm->tm_mon;
r->date.day = tm->tm_mday;
r->hour = tm->tm_hour;
r->min = tm->tm_min;
r->sec = tm->tm_sec;
r->date.month++;
if (r->date.month == 13)
{
r->date.month = 1;
r->date.year++;
}
}
#endif
/***********************************************************************/
void ARC_HANDLE::fill_date(ARC_RECORD *record)
{
unsigned char d1,d2;
d1 = read_char();
d2 = read_char();
record->date.year = ((d2 & 0xFE) >> 1) + 1980;
record->date.month = (d2 & 0x01)*8 + ((d1 & 0xE0) >> 5);
record->date.day = (d1 & 0x1F);
}
/***********************************************************************/
void ARC_HANDLE::fill_time(ARC_RECORD *record)
{
unsigned char d1,d2;
d1 = read_char();
d2 = read_char();
record->hour = (d2 & 0xF8) >> 3;
record->min = (d2 & 0x07)*8 + ((d1 & 0xE0) >> 5);
record->sec = (d1 & 0x1F) * 2;
}/****************************************************************/
#if SUPPORT_ARC
int ARC_HANDLE::get_record_arc7(ARC_RECORD *record, char *name)
{
int ch;
char string[255];
if (pos == 0)
{
pos+=29;
for (;;)
{
seek(pos, SEEK_SET);
ch = read_char();
pos+=ch;
seek(pos+1, SEEK_SET);
ch = read_char();
if (ch != 0)
break;
}
}
for (;;)
{
seek(pos+1, SEEK_SET);
ch = read_char();
switch (ch)
{
case EOF:
case 0:
return EOF;
case 2:
record->method = 1; break;
case 8:
record->method = 3; break;
case 10:
record->method = 25; break;
case 21:
pos += 15;
seek(pos, SEEK_SET);
ch = read_char();
pos += ch+14;
continue;
default:
record->method = 0;
}
break;
}
read_string(name);
seek(pos+15, SEEK_SET);
record->packed_size = read_long()+29; // 15
fill_date(record); // 19
fill_time(record); // 21
record->crc = (unsigned int)read_int(); // 23
record->unpacked_size = read_long(); // 25
pos+=record->packed_size;
return 0;
}
#endif
/****************************************************************/
#if SUPPORT_ARJ
int ARC_HANDLE::get_record_arj(ARC_RECORD *record, char *name)
{
int ch;
long pos2, old_pos;
int fn_len;
if (isFirst)
{
pos2 = pos + 34;
seek(pos2, SEEK_SET); // archive name starts here
pos = pos2 + 8;
while (read_char() > 0) // file name
pos++;
while (read_char() > 0) // comment
pos++;
isFirst = FALSE;
}
old_pos = pos;
seek(pos+5, SEEK_SET);
ch = read_char();
if (ch == 0 || ch == 26)
return EOF;
else if (ch == 4 && !is_self)
version = 60;
seek(pos+8, SEEK_SET);
ch = read_char();
if (ch & 0x01)
record->encrypted = TRUE;
ch = read_char(); // 9
switch (ch)
{
case EOF:
return EOF;
case 0:
record->method = 1; break;
case 1: case 2: case 3: case 4:
record->method = 17 + ch; break;
default:
record->method = 0;
}
seek(pos+12, SEEK_SET);
fill_time(record); // 12
fill_date(record); // 14
record->packed_size = read_long(); // 16
record->unpacked_size = read_long(); // 20
record->crc = read_long(); // 24
seek(pos+30, SEEK_SET);
record->attrib = read_long(); // 30
fn_len = read_string(name); // 34
while (read_char() > 0) // comment
fn_len++;
pos += record->packed_size + fn_len + 42;
if (pos <= old_pos || pos > old_pos+100000000)
return -2;
return 0;
}
#endif
/****************************************************************/
#if SUPPORT_DWC
int ARC_HANDLE::get_record_dwc(ARC_RECORD *record, char *name)
{
int ch;
if (pos == 0)
{
pos = -2;
while (pos > -256)
{
seek(pos, SEEK_END);
if (read_char() == 'D')
{
seek(pos-4, SEEK_END);
// number of embedded files
hold_n = read_long();
pos = seek(0, SEEK_CUR) - 24 - hold_n*34;
if (pos < 0)
return -2;
goto around;
}
pos--;
}
return -2;
}
around:
hold_n--;
if (hold_n < 0)
return EOF;
seek(pos, SEEK_SET);
read_string(name);
seek(pos+13, SEEK_SET);
record->unpacked_size = read_long(); // 13
my_localtime(read_long(), record); // 17
record->packed_size = read_long(); // 21
seek(pos+29, SEEK_SET);
ch = read_char();
if (ch == 1)
record->method = 3;
else if (ch == 2)
record->method = 1;
else
record->method = 0;
seek(pos+32, SEEK_SET);
record->crc = (unsigned int)read_int();
pos+=34;
return 0;
}
#endif
/****************************************************************/
#if SUPPORT_HA
int ARC_HANDLE::get_record_ha(ARC_RECORD *record, char *name)
{
long old_pos;
int ch, ch2;
int fn_len;
char path[FLENGTH];
char file_name[FLENGTH];
char *ptr;
if (pos == 0)
pos = 4;
old_pos = pos;
seek(pos, SEEK_SET);
ch = read_char();
if (ch == EOF)
return EOF;
else if (ch == 32)
record->method = 1; /* Stored */
else if (ch == 33)
record->method = 31; /* ASC */
else if (ch == 34)
record->method = 32; /* HSC */
else
record->method = 0; /* Unknown */
record->packed_size = read_long(); // 1
record->unpacked_size = read_long(); // 5
record->crc = read_long(); // 9
my_localtime(read_long(), record); // 13
read_string(path); // 17
read_string(file_name); // 17+path
read_int();
record->attrib = read_char();
pos += record->packed_size + strlen(path) + strlen(file_name) + 22;
strcpy(name, path);
if (name[0] != '\0')
{
/* Not sure what this is all about, but seems to be necessary */
if (name[strlen(name)-1] == -1)
name[strlen(name)-1] = '\0';
append_backslash(name);
}
strcat(name, file_name);
if (pos <= old_pos || pos > old_pos+100000000)
return -2;
return 0;
}
#endif
/****************************************************************/
#if SUPPORT_HAP
int ARC_HANDLE::get_record_hap(ARC_RECORD *record, char *name)
{
long old_pos;
int ch, ch2;
int fn_len;
char path[FLENGTH];
char file_name[FLENGTH];
char *ptr;
if (pos == 0)
pos = 15;
old_pos = pos;
seek(pos, SEEK_SET);
ch = read_char();
if (ch == EOF)
return EOF;
seek(pos+4, SEEK_SET);
record->packed_size = read_long(); // 4
seek(pos+17, SEEK_SET);
record->attrib = read_char(); // 16
fill_time(record); // 17
fill_date(record); // 19
seek(pos+22, SEEK_SET);
record->unpacked_size = read_long(); // 22
read(name, 12); // 26
name[12] = '\0';
seek(pos+39, SEEK_SET);
ch = read_char(); // 39
if (ch == 21)
record->method = 1; /* Stored */
else if (ch == 22)
record->method = 34; /* Learned */
else
record->method = 0; /* Unknown */
record->crc = 0;
pos += record->packed_size + 40;
if (pos <= old_pos || pos > old_pos+100000000)
return -2;
return 0;
}
#endif
/****************************************************************/
#if SUPPORT_HPK
int ARC_HANDLE::get_record_hpk(ARC_RECORD *record, char *name)
{
int ch, ch2, n;
if (pos == 0)
{
pos = -3;
while (pos > -256)
{
seek(pos, SEEK_END);
if (read_char() == 'H')
{
seek(pos-9, SEEK_END);
// number of embedded files
hold_n = read_int();
ch = read_int();
pos = seek(- 6L - ch, SEEK_CUR);
if (pos < 0)
return -2;
// Find the front of the file names, there should be a better way
n = hold_n;
while (n > 0)
{
ch = read_char(); // 0
ch2 = read_char(); // 1
(void)read_long();
if (ch2 & 0x10)
read_int();
if (ch2 & 0x80)
read_long();
else
read_int();
if (ch2 & 0x40)
read_long();
else
read_int();
if (ch2 & 0x01)
read_int();
n--;
}
trailer_pos = seek(0L, SEEK_CUR);
goto around;
}
pos--;
}
return -2;
}
around:
hold_n--;
if (hold_n < 0)
return EOF;
/* not sure exactly what the deal with the attributes is */
seek(pos-1, SEEK_SET);
record->attrib = read_char();
ch = read_char();
ch2 = read_char(); // 1
record->method = 33;
record->crc = 0;
if (ch2 & 0x10) /* attributes */
read_int();
else
record->attrib = 0x00;
my_localtime(read_long(), record); // 2
if (ch2 & 0x80)
record->unpacked_size = read_long();
else
record->unpacked_size = (unsigned int)read_int();
if (ch2 & 0x40)
record->packed_size = read_long();
else
record->packed_size = (unsigned int)read_int();
if (ch2 & 0x01)
read_int(); /* Something having to do with comments */
seek(trailer_pos, SEEK_SET);
read_string(name);
trailer_pos = seek(0, SEEK_CUR);
pos += 10;
if (ch2 & 0x10)
pos += 2;
if (ch2 & 0x40)
pos += 2;
if (ch2 & 0x80)
pos += 2;
if (ch2 & 0x01)
{
pos += 2;
goto around;
}
return 0;
}
#endif
/****************************************************************/
#if SUPPORT_HYP
int ARC_HANDLE::get_record_hyp(ARC_RECORD *record, char *name)
{
long old_pos;
int ch, ch2;
int fn_len;
char *ptr;
old_pos = pos;
seek(pos+1, SEEK_SET);
ch = read_char();
if (ch == EOF)
return EOF;
else if (ch == 'H')
record->method = 30; /* Hypered */
else
record->method = 1; /* Stored */
seek(pos+4, SEEK_SET);
record->packed_size = read_long(); // 4
record->unpacked_size = read_long(); // 8
fill_time(record); // 12
fill_date(record); // 14
seek(pos+20, SEEK_SET);
record->attrib = read_char(); // 20
fn_len = read_char(); // 21
if (fn_len >= SZ_NAME || fn_len < 0)
return -2;
read(name, fn_len);
name[fn_len] = '\0';
record->crc = 0;
pos += record->packed_size + fn_len + 22;
if (pos <= old_pos || pos > old_pos+100000000)
return -2;
return 0;
}
#endif
/****************************************************************/
#if SUPPORT_LBR
int ARC_HANDLE::get_record_lbr(ARC_RECORD *record, char *name)
{
DATE lbr_date;
long old_pos;
char temp[255];
int ch;
if (pos == 0)
{
seek(pos+14, SEEK_SET);
hold_n = read_char() + 2;
pos = 32;
}
old_pos = pos;
if (hold_n == 0)
return EOF;
for (;;)
{
seek(pos, SEEK_SET);
ch = read_char();
if (ch != 0)
{
pos+=32;
hold_n--;
if (hold_n == 0)
return EOF;
}
else
break;
}
seek(pos+1, SEEK_SET); /* Name */
read(name, 8);
name[8] = '\0';
rtrim(name);
strcat(name, ".");
read(temp, 3);
temp[3] = '\0';
strcat(name, temp);
seek(pos+14, SEEK_SET);
ch = read_char();
seek(pos+26, SEEK_SET);
record->packed_size = ch * 128 - read_char();
record->unpacked_size = record->packed_size;
seek(pos+16, SEEK_SET);
record->crc = (unsigned int)read_int();
{
lbr_date.year = 1977;
lbr_date.month = 12;
lbr_date.day = 31;
date_add(&lbr_date, &record->date, read_int()); /* 18*/
}
seek(pos+22, SEEK_SET);
fill_time(record);
hold_n--;
record->method = 1; /* Stored */
pos+=32;
if (pos <= old_pos || pos > old_pos+100000000)
return -2;
return 0;
}
#endif;
/****************************************************************/
#if SUPPORT_LZS || SUPPORT_LZH
int ARC_HANDLE::get_record_lzh(ARC_RECORD *record, char *name)
{
long old_pos;
int ch, ch2;
unsigned char d1;
char string[255];
char *ptr;
old_pos = pos;
seek(pos+4, SEEK_SET);
/* Additional version check */
ch = read_char();
if (ch == 'h')
{
if (version < 2) /* At least Lharc 1.xx */
version = 2;
}
/* Archive method */
ch = read_char();
switch(ch)
{
case EOF:
return EOF;
case '0':
record->method = 1;
break;
case '1':
record->method = 9;
break;
case '4':
case '5':
if (type == LZH)
{
if (ch == '5')
record->method = 10;
else
record->method = 22;
if (version < 3) /* At least lharc 2.x */
version = 3;
}
else
{
if (ch == '5')
record->method = 11;
else
record->method = 35;
}
break;
default:
return EOF;
}
seek(pos+7, SEEK_SET);
record->packed_size = read_long();
record->unpacked_size = read_long();
seek(pos+20, SEEK_SET);
ch = read_char();
d1 = 0;
if (ch < 2) /* Header level of 0 or 1 */
{
seek(pos+15, SEEK_SET);
fill_time(record);
fill_date(record);
if (ch == 0)
record->attrib = read_int();
seek(pos+21, SEEK_SET);
d1 = read_char();
read(string, d1);
string[d1] = '\0';
record->crc = (unsigned int)read_int();
if (ch == 1) /* Header level of 1 */
{
pos += 25 + d1;
read_char();
ch2 = read_int();
record->attrib = 0x00;
while (ch2 > 0)
{
ch = read_char();
if (ch == 0x02)
{
if (ch2-4 >= SZ_NAME || ch2-4 < 0)
return -2;
read(record->path, ch2-4);
record->path[ch2-4] = '\0';
read_char();
}
else if (ch == 0x40)
{
record->attrib = read_char();
}
pos+=ch2;
seek(pos, SEEK_SET);
record->packed_size -= ch2;
ch2 = read_int();
}
pos += 2 + record->packed_size;
}
else
pos+= 24 + d1 +record->packed_size;
}
else if (ch == 2)
{
seek(pos+15, SEEK_SET);
my_localtime(read_long(), record);
seek(pos+21, SEEK_SET);
record->crc = (unsigned int)read_int();
seek(pos+24, SEEK_SET);
pos += 24;
ch2 = read_int();
while (ch2 > 0)
{
ch = read_char();
if (ch == 1)
{
read(string, ch2-3);
string[ch2-3] = '\0';
}
else if (ch == 0x02)
{
if (ch2-4 >= SZ_NAME || ch2-4 < 0)
return -2;
read(record->path, ch2-4);
record->path[ch2-4] = '\0';
read_char();
}
else if (ch == 0x40)
{
record->attrib = read_char();
}
pos+=ch2;
seek(pos, SEEK_SET);
ch2 = read_int();
}
pos+= 2 + record->packed_size;
if (version < 3)
version = 3;
}
else
return -2;
/* Somehow Amiga .LZHs have the ability to stuff some sort of
comment into the name, this should take care of that */
{
if ((ptr = strchr(string, ' ')) != NULL)
*ptr = '\0';
if (strlen(string) > 80)
string[79] = '\0';
strcpy(name, string);
}
if (pos <= old_pos || pos > old_pos+100000000)
return -2;
return 0;
}
#endif
/****************************************************************/
#if SUPPORT_MD
int ARC_HANDLE::get_record_md(ARC_RECORD *record, char *name)
{
long old_pos;
int ch, ch2;
int fn_len;
char path[FLENGTH];
char file_name[FLENGTH];
char *ptr;
old_pos = pos;
seek(pos+24, SEEK_SET);
ch = read_char();
if (ch == EOF)
return EOF;
else if (ch == 0)
record->method = 1; /* Stored */
else if (ch == 1)
record->method = 36; /* LZW13 */
else
record->method = 0; /* Unknown */
record->unpacked_size = read_long(); // 25
record->packed_size = read_long(); // 29
record->attrib = read_int(); // 33
fill_time(record); // 35
fill_date(record); // 37
record->crc = (unsigned int)read_int(); // 39
ch = read_char(); // 41
read(name, ch); // 42
name[ch] = '\0';
pos += record->packed_size + 122;
if (pos <= old_pos || pos > old_pos+100000000)
return -2;
return 0;
}
#endif
/****************************************************************/
#if SUPPORT_PAK || SUPPORT_ARC
int ARC_HANDLE::get_record_pak(ARC_RECORD *record, char *name)
{
long old_pos;
int ch, ch2;
long next;
char string[255];
old_pos = pos;
seek(pos+1, SEEK_SET);
/* Archive method */
ch = read_char();
switch(ch)
{
case 0:
return EOF;
case 1:
case 2:
record->method = 1; break;
case 3:
record->method = 7; break;
case 4:
record->method = 6; break;
case 5: case 6:
record->method = 2; break;
case 7: case 8:
record->method = 3; break;
case 9:
if (version == 47)
version = 49;
record->method = 4;
break;
case 10:
record->method = 5; break;
case 11:
if (version >= 47 || version <= 49)
version = 50;
record->method = 8;
break;
default:
return -2;
}
/* name */
read_string(name);
seek(pos+15, SEEK_SET);
record->packed_size = read_long();
fill_date(record); // 19
fill_time(record); // 21
record->crc = (unsigned int)read_int(); // 23
record->unpacked_size = read_long(); // 25
pos += 29 + record->packed_size;
if (pos <= old_pos || pos > old_pos+100000000)
return -2;
/* Go after the trailer info */
while (trailer_pos > 0)
{
seek(trailer_pos, SEEK_SET);
ch = read_char();
if (ch == 0 || ch == EOF)
trailer_pos = -1;
else
{
ch2 = read_int();
next = read_long();
if (ch2 > rec_number)
break;
if (ch2 == rec_number && ch == 2)
{
if (next >= SZ_NAME || next < 0)
return -2;
read(record->path, next);
record->path[next] = '\0';
trailer_pos += next + 8;
break;
}
trailer_pos += next + 1;
seek(trailer_pos, SEEK_SET);
}
}
return 0;
}
#endif
/****************************************************************/
#if SUPPORT_RAR
int ARC_HANDLE::get_record_rar(ARC_RECORD *record, char *name)
{
long old_pos;
int ch, flags;
int fn_len;
int header_size;
char *ptr;
if (version == 81) /* RAR 1.50 > */
{
if (isFirst)
{
seek(pos + 12L, SEEK_SET);
pos += read_int() + 7;
isFirst = FALSE;
}
old_pos = pos;
seek(pos, SEEK_SET);
if (read_char() == EOF)
return EOF;
seek(pos, SEEK_SET);
read_int(); /* header CRC */
read_char(); /* header type */
flags = read_int(); // 3
header_size = read_int(); // 5
record->packed_size = read_long(); // 7
record->unpacked_size = read_long(); // 11
read_char(); /* Host operating system */
record->crc = read_long(); // 16
fill_time(record); // 20
fill_date(record); // 22
read_char(); /* version needed to extract */ // 24
ch = read_char(); // 25
if (ch == 0)
record->method = 1; /* Stored */
else if (ch >= '1' && ch <= '5')
record->method = 36 + ch - '0';
fn_len = read_int(); // 26
if (fn_len >= SZ_NAME || fn_len < 0)
return -2;
record->attrib = read_long(); // 28
read(name, fn_len); // 32
name[fn_len] = '\0';
/* Comment goes here if flags & 0x08 */
pos += record->packed_size + header_size;
}
else /* RAR 1.40 < */
{
if (isFirst)
{
seek(pos + 4L, SEEK_SET);
pos += read_int();
isFirst = FALSE;
}
old_pos = pos;
seek(pos, SEEK_SET);
if (read_char() == EOF)
return EOF;
seek(pos, SEEK_SET);
record->packed_size = read_long(); // 0
record->unpacked_size = read_long(); // 4
record->crc = (unsigned int)read_int(); // 8
seek(pos+12, SEEK_SET);
fill_time(record); // 12
fill_date(record); // 14
record->attrib = read_char(); // 16
flags = read_char(); // 17
read_char();
fn_len = read_char(); // 19
if (fn_len >= SZ_NAME || fn_len < 0)
return -2;
ch = read_char(); // 20
if (ch == 0)
record->method = 1; /* Stored */
else if (ch >= 1 && ch <= 5)
record->method = 36 + ch;
read(name, fn_len); // 21
name[fn_len] = '\0';
if (flags & 0x08)
ch = read_int() + 2; /* length of file comment */
else
ch = 0;
pos += record->packed_size + fn_len + ch + 21;
}
if (pos <= old_pos || pos > old_pos+100000000)
return -2;
return 0;
}
#endif
/****************************************************************/
#if SUPPORT_SQZ
int ARC_HANDLE::get_record_sqz(ARC_RECORD *record, char *name)
{
long old_pos;
int ch, ch2;
int fn_len;
char *ptr;
if (pos == 0)
{
pos = 8;
seek(pos, SEEK_SET);
ch = read_char();
if (ch == 1) /* header, skip it */
{
ch2 = read_int();
pos += ch2 + 3;
}
else
pos = 8;
}
old_pos = pos;
seek(pos, SEEK_SET);
fn_len = read_char() - 18;
if (fn_len >= SZ_NAME || fn_len < 0)
return EOF; /* Not sure what the true EOF condition is yet */
read_char(); /* Not sure what this byte is yet */
ch = read_char();
switch (ch)
{
case EOF:
return EOF;
case 0:
record->method = 1;
break;
case 1: case 2: case 3: case 4:
record->method = 17 + ch;
break;
default:
record->method = 0;
break;
}
record->packed_size = read_long(); // 3
record->unpacked_size = read_long(); // 7
fill_time(record); // 11
fill_date(record); // 13
record->attrib = read_char(); // 15
record->crc = read_long(); // 16
read(name, fn_len);
name[fn_len] = '\0';
pos += record->packed_size + fn_len + 20;
/* Remove double backslashes from the name, I don't know why sqz does this */
while ((ptr = strchr(name, '/')) != NULL)
*ptr = '\\';
while ((ptr = strstr(name, "\\\\")) != NULL)
memmove(ptr, ptr+1, strlen(ptr));
if (pos <= old_pos || pos > old_pos+100000000)
return -2;
return 0;
}
#endif
/****************************************************************/
#if SUPPORT_ZIP
int ARC_HANDLE::get_record_zip(ARC_RECORD *record, char *name)
{
long old_pos;
long sig;
int ch, ch2;
int fn_len;
/* Determine front of Central dir structure */
if (isFirst)
{
pos = -16;
while (seek(pos, SEEK_END) > 0)
{
sig = read_long();
if (sig == 0x06054B50)
{
seek(12, SEEK_CUR);
pos = read_long();
break;
}
pos--;
}
if (pos < 0)
return -2;
isFirst = FALSE;
}
old_pos = pos;
seek(pos, SEEK_SET);
sig = read_long(); /* Read centralized dir struct signature */
if (sig != 0x02014B50)
return EOF;
ch = read_char(); /* version made by */
switch (ch)
{
case 10:
if (version < 6 || version == 82)
version = 6;
break;
case 11:
if (version < 7 || version == 82)
version = 7;
break;
case 20:
if (version < 53 || version == 82)
version = 53;
break;
case 0:
version = 0;
return EOF;
default:
version = 82; /* Unknown zip type */
break;
}
read_char(); /* Host OS, Ver and OS needed to extact */
read_char();
read_char();
ch2 = read_int(); /* General purpose bit flag */
/* Archive method */
ch = read_int();
switch(ch)
{
case 0: /* Stored */
record->method = 1; break;
case 1: /* Shrunk */
record->method = 12; break;
case 2: case 3: case 4: case 5: /* Reduced */
record->method = 11+ch; break;
case 6: /* Implode */
record->method = 17;
// /* at least 1.0x since there is imploding done */
// if (version < 6)
// version = 6;
break;
case 8:
// if (version < 53)
// version = 53;
switch (ch2 & 0x06)
{
case 0:
record->method = 26; break; /* Deflated */
case 2:
record->method = 27; break; /* Deflated -EX */
case 4:
record->method = 28; break; /* Deflated -EF */
case 6:
record->method = 29; break; /* Deflated -ES */
}
if (ch2 & 0x01)
record->encrypted = TRUE;
break;
default:
record->method = 0; /* Unknown */
}
fill_time(record); // 12
fill_date(record); // 14
record->crc = read_long(); // 16
record->packed_size = read_long(); // 20
record->unpacked_size = read_long(); // 24
fn_len = read_int(); // 28
if (fn_len >= SZ_NAME || fn_len < 0)
return -2;
ch = read_int(); /* Extra field len */ // 30
ch2 = read_int(); /* File Comment len */ // 32
read_long(); /* Disk Number start and int file attr */ // 34
record->attrib = read_long(); // 38
read_long(); /* Position of local header */ // 42
read(name, fn_len); // 46
name[fn_len] = '\0';
pos = seek(ch + ch2, SEEK_CUR); /* Skip over extra field and comment */
if (pos <= old_pos || pos > old_pos+100000000)
return -2;
return 0;
#if 0
old_pos = pos;
seek(pos+2, SEEK_SET);
if (read_char() == 1)
{
seek(pos+4, SEEK_SET);
if (read_char() == 11)
if (version < 7 )
version = 7;
return EOF;
}
seek(pos+6, SEEK_SET);
if ((ch2 = read_char()) == EOF)
return EOF;
seek(pos+8, SEEK_SET);
if ((ch = read_char()) == EOF)
return EOF;
/* Archive method */
switch(ch)
{
case 0: /* Stored */
record->method = 1; break;
case 1: /* Shrunk */
record->method = 12; break;
case 2: case 3: case 4: case 5: /* Reduced */
record->method = 11+ch; break;
case 6: /* Implode */
record->method = 17;
/* at least 1.0x since there is imploding done */
if (version < 6)
version = 6;
break;
case 8:
if (version < 53)
version = 53;
switch (ch2 & 0x06)
{
case 0:
record->method = 26; break; /* Deflated */
case 2:
record->method = 27; break; /* Deflated -EX */
case 4:
record->method = 28; break; /* Deflated -EF */
case 6:
record->method = 29; break; /* Deflated -ES */
}
if (ch2 & 0x01)
record->encrypted = TRUE;
break;
default:
record->method = 0; /* Unknown */
}
read_char(); // 9
fill_time(record); // 10
fill_date(record); // 12
record->crc = read_long(); // 14
record->packed_size = read_long(); // 18
record->unpacked_size = read_long(); // 22
ch = read_int(); // 26
if (ch >= SZ_NAME || ch < 0)
return -2;
ch2 = read_int(); // 28
read(name, ch); // 30
name[ch] = '\0';
pos += 30+record->packed_size;
pos += ch+ch2;
if (pos <= old_pos || pos > old_pos+100000000)
return -2;
return 0;
#endif
}
#endif
/****************************************************************/
#if SUPPORT_ZOO
int ARC_HANDLE::get_record_zoo(ARC_RECORD *record, char *name)
{
long old_pos;
long next_pos;
int ch, ch2;
char string[255];
top:
if (pos == 0)
{
seek(pos+24, SEEK_SET);
ch = read_char();
if (ch == 34)
version = 62; /* 1.x */
else
version = 10; /* 2.x */
pos = ch+1;
}
around:
old_pos = pos;
seek(pos+4, SEEK_SET);
ch = read_char();
switch (ch)
{
case 0:
record->method = 1; break; // stored
case 1:
record->method = 23; break; // Normal
case 2:
record->method = 24; // High
if (version != 59)
version = 51; // therefore ZOO 2.10
break;
case EOF:
return EOF;
default:
record->method = 0; break; // Unknown
}
next_pos = read_long()+1;
seek(pos+13, SEEK_SET);
fill_date(record); // 13
fill_time(record); // 15
record->crc = (unsigned int)read_int(); // 17
record->unpacked_size = read_long(); // 19
record->packed_size = read_long(); // 23
if (record->packed_size == 0)
{
pos+=27;
while ((ch = read_char())!=0xA7)
{
if (ch == EOF)
return EOF;
pos++;
}
goto around;
}
seek(pos+29, SEEK_SET);
if (read_char() == 1)
{
/* Deleted file */
pos = next_pos;
goto top;
}
seek(pos+37, SEEK_SET);
read_string(string);
seek(pos+55, SEEK_SET);
ch = read_char();
ch2= read_char();
if (ch != 64) // Not sure what this is all about yet
{
if (ch != 0)
{
if (ch >= SZ_NAME || ch < 0)
return -2;
read(string, ch);
string[ch] = '\0';
}
if (ch2 == 0)
strcpy(name, string);
else
{
read_string(name);
strcat(name, "\\");
strcat(name, string);
}
}
else
strcpy(name, string);
pos = next_pos;
if (pos <= old_pos || pos > old_pos+100000000)
return -2;
return 0;
}
#endif
/****************************************************************/
int ARC_HANDLE::get_record(AU *, ARC_RECORD *record)
{
int retCode;
char name[SZ_NAME];
record->method = 0; /* unknown until otherwise */
record->name[0] = '\0';
record->path[0] = '\0';
record->encrypted = FALSE;
rec_number++;
switch (type)
{
#if SUPPORT_ARC
case ARC7:
retCode = get_record_arc7(record, name);
break;
#endif
#if SUPPORT_ARJ
case ARJ:
retCode = get_record_arj(record, name);
break;
#endif
#if SUPPORT_DWC
case DWC:
retCode = get_record_dwc(record, name);
break;
#endif
#if SUPPORT_MD
case MD:
retCode = get_record_md(record, name);
break;
#endif
#if SUPPORT_HA
case HA:
retCode = get_record_ha(record, name);
break;
#endif
#if SUPPORT_HAP
case HAP:
retCode = get_record_hap(record, name);
break;
#endif
#if SUPPORT_HPK
case HPK:
retCode = get_record_hpk(record, name);
break;
#endif
#if SUPPORT_HYP
case HYP:
retCode = get_record_hyp(record, name);
break;
#endif
#if SUPPORT_LBR
case LBR:
retCode = get_record_lbr(record, name);
break;
#endif
#if SUPPORT_LZS || SUPPORT_LZH
case LZS:
case LZH:
retCode = get_record_lzh(record, name);
break;
#endif
#if SUPPORT_PAK || SUPPORT_ARC
case PAK:
case ARC:
retCode = get_record_pak(record, name);
break;
#endif
#if SUPPORT_RAR
case RAR:
retCode = get_record_rar(record, name);
break;
#endif
#if SUPPORT_SQZ
case SQZ:
retCode = get_record_sqz(record, name);
break;
#endif
#if SUPPORT_ZIP
case ZIP:
retCode = get_record_zip(record, name);
break;
#endif
#if SUPPORT_ZOO
case ZOO:
retCode = get_record_zoo(record, name);
break;
#endif
default: /* not supported but known */
return -3;
}
if (retCode == 0)
{
if (record->path[0] == '\0')
{
fix_path(name);
split_file(name, record->path, record->name);
}
else
strcpy(record->name, name);
if (record->packed_size < 0 || record->unpacked_size < 0)
return -2;
}
return retCode;
}